﻿///////////////////////////////////////////////////////////////////////////////////////////////////////////
// Mootools 1.1 to 1.2 compatible layer libraries.
(function(){
	oldA = $A;
	window.$A = function(iterable, start, length){
		if (start != undefined && length != undefined) {
			//MooTools.upgradeLog('1.1 > 1.2: $A no longer takes start and length arguments.');
			if (Browser.Engine.trident && $type(iterable) == 'collection'){
				start = start || 0;
				if (start < 0) start = iterable.length + start;
				length = length || (iterable.length - start);
				var array = [];
				for (var i = 0; i < length; i++) array[i] = iterable[start++];
				return array;
			}
			start = (start || 0) + ((start < 0) ? iterable.length : 0);
			var end = ((!$chk(length)) ? iterable.length : length) + start;
			return Array.prototype.slice.call(iterable, start, end);
		}
		return oldA(iterable);
	};


	var strs = ['Array', 'Function', 'String', 'RegExp', 'Number', 'Window', 'Document', 'Element', 'Elements'];
	for (var i = 0, l = strs.length; i < l; i++) {
		var type = strs[i];
		var natv = window[type];
		if (natv) {
			var extend = natv.extend;
			natv.extend = function(props){
				//MooTools.upgradeLog('1.1 > 1.2: native types no longer use .extend to add methods to prototypes but instead use .implement. NOTE: YOUR METHODS WERE NOT IMPLEMENTED ON THE NATIVE ' + type.toUpperCase() + ' PROTOTYPE.');
				return extend.apply(this, arguments);
			};
		}
	}
})();

window.onDomReady = Window.onDomReady = function(fn){
	//MooTools.upgradeLog('1.1 > 1.2: window.onDomReady is no longer supported. Use window.addEvent("domready") instead');
	return window.addEvent('domready', fn);
};if (Browser.__defineGetter__) {
	Browser.__defineGetter__('hasGetter',function(){
		return true;
	});
}

if(Browser.hasGetter){ // webkit, gecko, opera support
	
	window.__defineGetter__('ie',function(){
		//MooTools.upgradeLog('1.1 > 1.2: window.ie is deprecated. Use Browser.Engine.trident');
		return (Browser.Engine.name == 'trident') ? true : false;
	});
	window.__defineGetter__('ie6',function(){
		//MooTools.upgradeLog('1.1 > 1.2: window.ie6 is deprecated. Use Browser.Engine.trident and Browser.Engine.version');
		return (Browser.Engine.name == 'trident' && Browser.Engine.version == 4) ? true : false;
	});
	window.__defineGetter__('ie7',function(){
		//MooTools.upgradeLog('1.1 > 1.2: window.ie7 is deprecated. Use Browser.Engine.trident and Browser.Engine.version');
		return (Browser.Engine.name == 'trident' && Browser.Engine.version == 5) ? true : false;
	});
	window.__defineGetter__('gecko',function(){
		//MooTools.upgradeLog('1.1 > 1.2: window.gecko is deprecated. Use Browser.Engine.gecko');
		return (Browser.Engine.name == 'gecko') ? true : false;
	});
	window.__defineGetter__('webkit',function(){
		//MooTools.upgradeLog('1.1 > 1.2: window.webkit is deprecated. Use Browser.Engine.webkit');
		return (Browser.Engine.name == 'webkit') ? true : false;
	});
	window.__defineGetter__('webkit419',function(){
		//MooTools.upgradeLog('1.1 > 1.2: window.webkit is deprecated. Use Browser.Engine.webkit and Browser.Engine.version');
		return (Browser.Engine.name == 'webkit' && Browser.Engine.version == 419) ? true : false;
	});
	window.__defineGetter__('webkit420',function(){
		//MooTools.upgradeLog('1.1 > 1.2: window.webkit is deprecated. Use Browser.Engine.webkit and Browser.Engine.version');
		return (Browser.Engine.name == 'webkit' && Browser.Engine.version == 420) ? true : false;
	});
	window.__defineGetter__('opera',function(){
		//MooTools.upgradeLog('1.1 > 1.2: window.opera is deprecated. Use Browser.Engine.presto');
		return (Browser.Engine.name == 'presto') ? true : false;
	});
} else {
	window[Browser.Engine.name] = window[Browser.Engine.name + Browser.Engine.version] = true;
	window.ie = window.trident;
	window.ie6 = window.trident4;
	window.ie7 = window.trident5;	
}

//legacy .extend support

(function(){
	var proto = function(obj) {
		var f = function(){
			return this;
		};
		f.prototype = obj;
		return f;
	};

	Class.prototype.extend = function(properties){
		//MooTools.upgradeLog('1.1 > 1.2: Class.extend is deprecated. See the class Extend mutator.');
		var maker = proto(properties);
		var made = new maker();
		made.Extends = this;
		return new Class(made);
	};

	var __implement = Class.prototype.implement;
	Class.prototype.implement = function(){
		if (arguments.length > 1 && Array.every(arguments, Object.type)){
			//MooTools.upgradeLog('1.1 > 1.2: Class.implement no longer takes more than one thing at a time, either MyClass.implement(key, value) or MyClass.implement(object) but NOT MyClass.implement(new Foo, new Bar, new Baz). See also: the class Implements mutator.');
			Array.each(arguments, function(argument){
				__implement.call(this, argument);
			}, this);
			return this;
		}
		return __implement.apply(this, arguments);
	};
})();

Array.implement({

	copy: function(start, length){
		//MooTools.upgradeLog('1.1 > 1.2: Array.copy is deprecated. Use Array.splice');
		return $A(this, start, length);
	},

	remove : function(item){
		//MooTools.upgradeLog('1.1 > 1.2: Array.remove is deprecated. Use Array.erase');
		return this.erase(item);
	},

	merge : function(array){
		//MooTools.upgradeLog('1.1 > 1.2: Array.merge is deprecated. Use Array.combine');
		return this.combine(array);
	}

});

Array.alias({'remove':'erase', 'merge':'combine'});

Function.implement({

	bindAsEventListener: function(bind, args){
		//MooTools.upgradeLog('1.1 > 1.2: Function.bindAsEventListener is deprecated. Use bindWithEvent.');
		return this.bindWithEvent.call(this, bind, args);
	}

});

Function.empty = function(){
	//MooTools.upgradeLog('1.1 > 1.2: Function.empty is now just $empty.');
	return $empty;
}

Hash.alias({keys: 'getKeys',values : 'getValues', hasKey: 'has', merge: 'combine'});

/*
Object.toQueryString = function(obj){
	//MooTools.upgradeLog('1.1 > 1.2: Object.toQueryString() is deprecated. use Hash.toQueryString() instead');
	$H(obj).each(function(item, key){
		if ($type(item) == 'object' || $type(item) == 'array'){
			obj[key] = item.toString();
		}
	});
	return Hash.toQueryString(obj);
};
*/
var Abstract = function(obj){
	//MooTools.upgradeLog('1.1 > 1.2: Abstract is deprecated. Use Hash');
	return new Hash(obj);
};

Class.empty = function(){ 
	//MooTools.upgradeLog('1.1 > 1.2: replace Class.empty with $empty');
	return $empty;
};

Element.extend = Element.implement;

Elements.extend = Elements.implement;


(function(){

	var toQueryString = Element.prototype.toQueryString;

	Element.implement({
	  injectInside:function(el){
		  return this.inject(el,'inside');
	  },
	
    injectBefore:function(el){
		  return this.inject(el,'before');
	  },

	  injectAfter:function(el){
		  return this.inject(el,'after');
	  },
	
    injectTop:function(el){
		  return this.inject(el,'top');
	  },

    injectBottom:function(el){
		  return this.inject(el,'bottom');
	  },
		getFormElements: function(){
			//MooTools.upgradeLog('1.1 > 1.2: Element.getFormElements is deprecated, use Element.getElements("input, textarea, select");'); 
			return this.getElements('input, textarea, select');
		},

		replaceWith: function(el){
			//MooTools.upgradeLog('1.1 > 1.2: Element.replaceWith is deprecated, use Element.replaces instead.'); 
			el = $(el);
			this.parentNode.replaceChild(el, this);
			return el;
		},

		remove: function() {
			//MooTools.upgradeLog('1.1 > 1.2: Element.remove is deprecated - use Element.dispose.');
			return this.dispose.apply(this, arguments);
		},

		getText: function(){
			//MooTools.upgradeLog('1.1 > 1.2: Element.getText is deprecated - use Element.get("text").'); 
			return this.get('text');
		},

		setText: function(text){
			//MooTools.upgradeLog('1.1 > 1.2: Element.setText is deprecated - use Element.set("text", text).'); 
			return this.set('text', text);
		},

		setHTML: function(){
			//MooTools.upgradeLog('1.1 > 1.2: Element.setHTML is deprecated - use Element.set("html", HTML).'); 
			return this.set('html', arguments);
		},

		getHTML: function(){
			//MooTools.upgradeLog('1.1 > 1.2: Element.getHTML is deprecated - use Element.get("html").'); 
			return this.get('html');
		},

		getTag: function(){
			//MooTools.upgradeLog('1.1 > 1.2: Element.getTag is deprecated - use Element.get("tag").'); 
			return this.get('tag');
		},
	
		getValue: function(){
			//MooTools.upgradeLog('1.1 > 1.2: Element.getValue is deprecated - use Element.get("value").');
			switch(this.getTag()){
				case 'select':
					var values = [];
					$each(this.options, function(option){
						if (option.selected) values.push($pick(option.value, option.text));
					});
					return (this.multiple) ? values : values[0];
				case 'input': if (!(this.checked && ['checkbox', 'radio'].contains(this.type)) && !['hidden', 'text', 'password'].contains(this.type)) break;
				case 'textarea': return this.value;
			}
			return false;
		},

		toQueryString: function(){
			//MooTools.upgradeLog('1.1 > 1.2: warning Element.toQueryString is slightly different; inputs without names are excluded, inputs with type == submit, reset, and file are excluded, and inputs with undefined values are excluded.');
			return toQueryString.apply(this, arguments);
		},
	  removeElements: function(){
		  return this.dispose();
	  }
	});
})();

Element.alias({'remove':'dispose','getLastChild':'getLast'});

Element.implement({

    // Terrence
    setMany: function(el, method, pairs){
        for (var key in pairs) el[method](key, pairs[key]);
        return el;
    },

    getSize: function(){
	    return {
		'scroll': {'x': this.scrollLeft, 'y': this.scrollTop},
		'size': {'x': this.offsetWidth, 'y': this.offsetHeight},
		'scrollSize': {'x': this.scrollWidth, 'y': this.scrollHeight},
		x : this.offsetWidth,
		y : this.offsetHeight
	    };
	},
    

	setStyles: function(source){
		switch($type(source)){
			case 'object': this.setMany(this, 'setStyle', source); break;
			case 'string': this.style.cssText = source;
		}
		return this;
	},
/*	
    getCoordinates: function(overflown){
		var position = this.getPosition(overflown);
		var obj = {
			'width': this.offsetWidth,
			'height': this.offsetHeight,
			'left': position.x,
			'top': position.y
		};
		obj.right = obj.left + obj.width;
		obj.bottom = obj.top + obj.height;
		
		return obj;
	}
	
		getCoordinates: function(element){
		if (isBody(this)) return this.getWindow().getCoordinates();
		var position = this.getPosition(element), size = this.getSize();
		var obj = {left: position.x, top: position.y, width: size.x, height: size.y};
		obj.right = obj.left + obj.width;
		obj.bottom = obj.top + obj.height;
		return obj;
	},
*/
    //
    
	getText: function(){
		return this.get('text');
	},

	setText: function(text){
		return this.set('text', text);
	},

	setHTML: function(){
		return this.set('html', arguments);
	},
	
	getHTML: function(){
		return this.get('html');
	},

	getTag: function(){
		return this.get('tag');
	}

});

(function(){

	var getPosition = Element.prototype.getPosition;
	var getCoordinates = Element.prototype.getCoordinates;

	function isBody(element){
		return (/^(?:body|html)$/i).test(element.tagName);
	};

	var getSize = Element.prototype.getSize;

	Element.implement({
	
		getSize: function(){
			//MooTools.upgradeLog('1.1 > 1.2: NOTE: getSize is different in 1.2; it no longer returns values for size, scroll, and scrollSize, but instead just returns x/y values for the dimensions of the element.');
			var size = getSize.apply(this, arguments);
			return $merge(size, {
				size: size,
				scroll: this.getScroll(),
				scrollSize: this.getScrollSize()
			});
		},

		getPosition: function(relative){
			if (relative && $type(relative) == "array") {
				//MooTools.upgradeLog('1.1 > 1.2: Element.getPosition no longer accepts an array of overflown elements but rather, optionally, a single element to get relative coordinates.');
				relative = null;
			}
			return getPosition.apply(this, [relative]);
		},

		getCoordinates: function(relative){
			if (relative && $type(relative) == "array") {
				//MooTools.upgradeLog('1.1 > 1.2: Element.getCoordinates no longer accepts an array of overflown elements but rather, optionally, a single element to get relative coordinates.');
				relative = null;
			}
			return getCoordinates.apply(this, [relative]);
		}
	
	});

	Native.implement([Document, Window], {

		getSize: function(){
			//MooTools.upgradeLog('1.1 > 1.2: NOTE: getSize is different in 1.2; it no longer returns values for size, scroll, and scrollSize, but instead just returns x/y values for the dimensions of the element.');
			var size;
			var win = this.getWindow();
			var doc = this.getDocument();
			doc = (!doc.compatMode || doc.compatMode == 'CSS1Compat') ? doc.html : doc.body;
			if (Browser.Engine.presto || Browser.Engine.webkit){
				size =  {x: win.innerWidth, y: win.innerHeight};
			} else {
				size = {x: doc.clientWidth, y: doc.clientHeight};
			}
			return $extend(size, {
				size: size,
				scroll: {x: win.pageXOffset || doc.scrollLeft, y: win.pageYOffset || doc.scrollTop},
				scrollSize: {x: Math.max(doc.scrollWidth, size.x), y: Math.max(doc.scrollHeight, size.y)}
			});
		}

	});

})();

Event.keys = Event.Keys;

Element.implement({
	
	setOpacity: function(op){
		return this.set('opacity', op);
	}
	
});

//Object.toQueryString = Hash.toQueryString;

var XHR = new Class({
	Extends: Request,
	options: {
		update: false
	},

	initialize: function(url, options){
		this.setOptions(options);
		this.parent(this.options);
		this.url = url;
	},

	request: function(){
	   return this.send(this.url);
	},

	send: function(url){
		if (!this.check(arguments.callee, url)) return this;
		this.options.url=url;
		return this.parent(this.options);
	},

	success: function(text, xml){
		text = this.processScripts(text);
		if (this.options.update) $(this.options.update).empty().set('html', text);
		
		// Terrence
		this.transport = this.response;
		this.transport.responseXML = this.response.xml;
		// 
		
		this.onSuccess(text, xml);
	},
	
	failure: function(){
		this.fireEvent('failure', this.xhr);
		// Terrence
		this.transport = this.response;
		this.transport.responseXML = this.response.xml;
		//
	}

});

var Ajax = XHR;

JSON.Remote = new Class({

	options: {
		key: 'json'
	},

	Extends: Request.JSON,

	initialize: function(url, options){
		this.parent(options);
		this.onComplete = $empty;
		this.url = url;
	},

	send: function(data){
		if (!this.check(arguments.callee, data)) return this;
		return this.parent({url: this.url, data: {json: Json.encode(data)}});
	},
	
	failure: function(){
		this.fireEvent('failure', this.xhr);
	}

});


Fx.implement({

	custom: function(from, to){
		return this.start(from, to);
	},

	clearTimer: function(){
		return this.cancel();
	},
	
	stop: function(){
		return this.cancel();
	}

});

Fx.Base = Fx;

Fx.Style = function(element, property, options){
	return new Fx.Tween(element, $extend({property: property}, options));
};


Element.implement({
	
	effect: function(property, options){
		return new Fx.Tween(this, $extend({property: property}, options));
	}

});

Fx.Styles = Fx.Morph;

Element.implement({
	
	effects: function(options){
		return new Fx.Morph(this, options);
	}

});
/*
Native.implement([Element, Document], {

	getElementsByClassName: function(className){
		//MooTools.upgradeLog('1.1 > 1.2: Element.filterByTag is deprecated.');
		
		return this.getElements('.' + className);
	},

	getElementsBySelector: function(selector){
		//MooTools.upgradeLog('1.1 > 1.2: Element.getElementsBySelector is deprecated. Use getElements()');
		return this.getElements(selector);
	}

});
*/
Elements.implement({

	filterByTag: function(tag){
		return this.filter(tag);
	},

	filterByClass: function(className){
		return this.filter('.' + className);
	},

	filterById: function(id){
		return this.filter('#' + id);
	},

	filterByAttribute: function(name, operator, value){
		return this.filter('[' + name + (operator || '') + (value || '') + ']');
	}

});

var $E = function(selector, filter){
	return ($(filter) || document).getElement(selector);
};

var $ES = function(selector, filter){
	return ($(filter) || document).getElements(selector);
};

var Json = JSON;

JSON.toString = JSON.encode;
JSON.evaluate = JSON.decode;

Cookie.set = function(key, value, options){
	return new Cookie(key, options).write(value);
};

Cookie.get = function(key){
    // Terrence
    var rc = new Cookie(key).read();
    if (rc == null) return false;
	return rc;
	//
};

Cookie.remove = function(key, options){
	return new Cookie(key, options).dispose();
};


Fx.Scroll.implement({

	scrollTo: function(y, x){
		return this.start(y, x);
	}

});


(function(){
	if (!window.Tips) return;

	Tips.implement({

		initialize: function(){
			//MooTools.upgradeLog('1.1 > 1.2: Tips DOM element layout has changed and your CSS classes may need to change.');
			var params = Array.link(arguments, {options: Object.type, elements: $defined});
			this.setOptions(params.options);
			if (this.options.offsets) {
				//MooTools.upgradeLog('1.1 > 1.2: Tips no longer have an "offsets" option; use "offset".');
				this.options.offset = this.options.offsets;
			}
			document.id(this);
			this.addEvent('show', function(){
				this.tip.addClass('tool-tip');
				this.tip.getElement('.tip-title').addClass('tool-title');
				this.tip.getElement('.tip-text').addClass('tool-text');
			});
			this.parseTitle(params.elements);
			if (params.elements) this.attach(params.elements);
		},

		parseTitle: function(elements){
			elements.each(function(element){
			var title = element.get('title');
				if (title.test('::')) {
					//MooTools.upgradeLog('1.1 > 1.2: Tips no longer parse the title attribute for "::" for title/caption; use title and rel attributes instead.');
					element.store('tip:title', title.split('::')[0]);
					element.store('tip:text', title.split('::')[1]);
					element.set('title', '');
				}
			});
		}

	});

})();

$extend(Element.NativeEvents, {
    'paste': 2, 'input': 2
});
Element.Events.paste = {
    base : (Browser.Engine.presto || (Browser.Engine.gecko && Browser.Engine.version < 19))? 'input': 'paste',
    condition: function(e){
        this.fireEvent('paste', e, 1);
        return false;
    }
};